package com.such.kitx.tax.fastin;

import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import com.such.kit.Logger;
import com.such.kit.datacast.CastCommons;
import com.such.kit.file.FileCommons;
import com.such.kit.remote.WebServiceCommons;
import com.such.kit.resource.support.ReadResource;
import com.such.kit.string.StringCommons;
import com.such.kit.validate.ValidateCommons;

/**
 * @author SUCH
 * <pre>
 * 基于 税控发票开票软件发票信息数据接口规范 的发票信息快速导入代理服务
 * 
 * 警告：此接口需要依赖开票客户端的批量导入功能
 * </pre>
 */
public class AgentServer {

	private static String resourceName = "fastin-agent";
	private static String reportMethod = "getReport";

	private String filePath;
	private String resultPath;
	private String address;
	private String taxVendor;
	private String version;
	private String commodityCodeVersion;
	private int scanInterval;

	public AgentServer(String filePath, String resultPath, String address, String taxVendor, String version, String commodityCodeVersion, int scanInterval) {
		this.filePath = filePath;
		this.resultPath = resultPath;
		this.address = address;
		this.taxVendor = taxVendor;
		this.version = version;
		this.commodityCodeVersion = commodityCodeVersion;
		this.scanInterval = scanInterval;
	}

	public void start() throws InterruptedException {
		Logger.info(getClass(), "FastIn 代理服务启动");
		while (true) {
			try {
				getReport();
			} catch (Exception e) {
				Logger.error(getClass(), "调用远端接口失败", e);
			} finally {
				Logger.info(getClass(), StringCommons.merger("FastIn 代理服务休眠 [", this.scanInterval, "] 秒，等待下次执行"));
				Thread.sleep(this.scanInterval * 1000);
			}
		}
	}

	public void getReport() throws Exception {
		LinkedHashMap<String, String> params = new LinkedHashMap<String, String>();
		params.put("taxVendor", this.taxVendor);
		params.put("version", this.version);
		params.put("commodityCodeVersion", this.commodityCodeVersion);
		Logger.info(getClass(), "调用远端接口获取报文.开始");
		String report = WebServiceCommons.invoke(this.address, reportMethod, params);
		Logger.debug(getClass(), StringCommons.merger("获取报文：", StringCommons.NEW_LINE, report));

		if (ValidateCommons.isNotEmpty(report)) {
			String name = CastCommons.dateToString(new Date(), CastCommons.DATE_TIME_NUMBER);
			String path = StringCommons.merger(FileCommons.appendPathNode(this.filePath, name), ".tmp");
			Logger.info(getClass(), StringCommons.merger("输出临时文件 [", path, "].开始"));
			FileCommons.createFile(new InputStreamReader(new ByteArrayInputStream(report.getBytes()), StringCommons.CHARSET_UTF8), path);
			Logger.info(getClass(), StringCommons.merger("输出临时文件 [", path, "].结束"));

			Logger.info(getClass(), StringCommons.merger("重命名文件 [", path, "].开始"));
			FileCommons.rename(path, StringCommons.merger(name, ".xml"));
			Logger.info(getClass(), StringCommons.merger("重命名文件 [", path, "].结束"));
		} else {
			Logger.info(getClass(), "获取到的报文为空");
		}
		Logger.info(getClass(), "调用远端接口获取报文.结束");
	}

	/**
	 * <pre>
	 * 主方法
	 * 为脚本启动提供入口
	 * </pre>
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		int argLen = args.length;
		if (argLen == 0) {
			Logger.info(AgentServer.class, StringCommons.merger("从 ", resourceName, ".properties 中加载配置"));
			List<String> keys = ReadResource.getKeys(resourceName);
			if (ValidateCommons.isNotEmpty(keys)) {
				argLen = keys.size();
				args = new String[argLen];
				for (int i = 0; i < argLen; i++) {
					args[i] = ReadResource.getValue(resourceName, keys.get(i));
				}
			}
		}
		if (argLen < 7) {
			throw new Exception("缺少关键参数 [数据文件路径, 导入结果路径, WebService 服务地址, 税控服务厂商, 接口版本, 商品编码版本, 扫描间隔（秒）]");
		}
		String filePath = args[0];
		String resultPath = args[1];
		String address = args[2];
		String taxVendor = args[3];
		String version = args[4];
		String commodityCodeVersion = args[5];
		int scanInterval = CastCommons.stringToInteger(args[6]);
		new AgentServer(filePath, resultPath, address, taxVendor, version, commodityCodeVersion, scanInterval).start();
	}

}
